0%

SpringAI — 模型评估

概述

测试 AI 应用需要对生成的内容进行评估,以确保 AI 模型没有产生幻觉(hallucinated)响应。
一种评估响应的方法是使用 AI 模型本身进行评估,选择最适合评估的 AI 模型,它可能与用于生成响应的模型不同。

Evaluator 接口

Spring AI 用于评估响应的接口是 Evaluator,定义如下:

1
2
3
4
5
6
public interface Evaluator {

EvaluationRequest createEvaluationRequest(String userText, List<String> dataList, String responseContent);

EvaluationResponse evaluate(EvaluationRequest evaluationRequest);
}

EvaluationRequest

评估的输入是 EvaluationRequest,定义如下:

字段 说明
userText 用户的原始输入,类型为 String
dataList 上下文数据,例如来自检索增强生成(RAG)的数据,附加到原始输入之后
responseContent AI 模型的响应内容,类型为 String

EvaluationResponse

EvaluationResponse 包含评估结果,主要方法包括:

方法 说明
boolean isRelevant() (RelevancyEvaluator)响应是否与用户输入和上下文相关
boolean isSupported() (FactCheckingEvaluator)陈述是否得到文档支持
String getExplanation() 获取评估的详细解释(如果有)
Map<String, Object> getMetadata() 获取评估的元数据信息

RelevancyEvaluator(相关性评估器)

RelevancyEvaluatorEvaluator 接口的一个实现,旨在根据提供的上下文评估 AI 生成响应的相关性。该评估器通过判断 AI 模型的响应是否与用户的输入以及检索到的上下文相关,来帮助评估 RAG 流程的质量。

评估基于以下三方面:

  1. 用户输入
  2. AI 模型的响应
  3. 上下文信息

它使用一个提示词模板来询问 AI 模型:该响应是否与用户输入和上下文相关。

默认提示词模板

RelevancyEvaluator 使用的默认提示词模板如下:

1
2
3
4
5
6
7
8
9
You are an evaluator tasked with determining if the response provided by an AI system is relevant to the user's question and the given context.

User Question: {query}

AI System Response: {response}

Given Context: {context}

Is the AI system response relevant to the user question and context? Answer with 'yes' or 'no'.

使用示例

以下是一个在集成测试中使用 RelevancyEvaluator 的示例,验证使用 RetrievalAugmentationAdvisor 的 RAG 流程结果:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
@SpringBootTest
class RagFlowIntegrationTest {

@Autowired
private ChatClient chatClient;

@Autowired
private VectorStore vectorStore;

@Test
void testRagFlowRelevancy() {
// 准备测试数据
String userQuestion = "What is the capital of France?";
String expectedContext = "France is a country in Europe. Its capital is Paris.";

// 将上下文存入向量存储
vectorStore.add(List.of(new Document(expectedContext)));

// 构建 RAG 流程
ChatClient.CallResponseSpec responseSpec = chatClient.prompt()
.user(userQuestion)
.advisors(new RetrievalAugmentationAdvisor(vectorStore))
.call();

String response = responseSpec.content();

// 使用 RelevancyEvaluator 评估响应相关性
RelevancyEvaluator evaluator = new RelevancyEvaluator(
ChatClient.builder(chatModel).build()
);

EvaluationRequest evaluationRequest = evaluator.createEvaluationRequest(
userQuestion,
List.of(expectedContext),
response
);

EvaluationResponse evaluationResponse = evaluator.evaluate(evaluationRequest);

// 断言评估结果为相关
assertTrue(evaluationResponse.isRelevant());
}
}

自定义提示词模板

RelevancyEvaluator 使用默认模板来提示 AI 模型进行评估。你可以通过 .promptTemplate() 构建器方法提供自己的 PromptTemplate 对象来自定义此行为:

1
2
3
RelevancyEvaluator evaluator = new RelevancyEvaluator(
ChatClient.builder(chatModel).build()
).promptTemplate(customPromptTemplate);

自定义 PromptTemplate 可以使用任何 TemplateRenderer 实现(默认使用基于 StringTemplate 引擎的 StPromptTemplate)。重要要求是模板必须包含以下占位符:

占位符 说明
query 接收用户问题
response 接收 AI 模型的响应
context 接收上下文信息

FactCheckingEvaluator(事实核查评估器)

FactCheckingEvaluatorEvaluator 接口的另一个实现,旨在根据提供的上下文评估 AI 生成响应的 factual accuracy(事实准确性)。该评估器通过验证给定的陈述(claim)是否在逻辑上得到提供的上下文(document)的支持,来帮助检测和减少 AI 输出中的幻觉。

将”claim”(陈述)和”document”(文档)呈现给 AI 模型进行评估。目前有一些专门用于此目的的小型高效 AI 模型,例如 Bespoke 的 Minicheck,与 GPT-4 等旗舰模型相比,它有助于降低执行这些检查的成本。Minicheck 也可以通过 Ollama 使用。

构造函数

FactCheckingEvaluator 的构造函数接受一个 ChatClient.Builder 作为参数:

1
2
3
4
5
6
7
public FactCheckingEvaluator(ChatClient.Builder chatClientBuilder) {
this(chatClientBuilder, null);
}

public FactCheckingEvaluator(ChatClient.Builder chatClientBuilder, PromptTemplate promptTemplate) {
// ...
}

默认提示词模板

该评估器使用以下提示词模板进行事实核查:

1
2
3
4
5
6
7
You are a fact-checking assistant. Your task is to determine if the given claim is supported by the provided document.

Document: {document}

Claim: {claim}

Is the claim supported by the document? Answer with 'yes' or 'no'.

其中:

  • {document} 是上下文信息
  • {claim} 是要评估的 AI 模型响应

使用示例

以下是如何将 FactCheckingEvaluator 与基于 Ollama 的 ChatModel 配合使用, specifically the Bespoke-Minicheck 模型的示例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
@SpringBootTest
class FactCheckingIntegrationTest {

@Test
void testFactCheckingWithMinicheck() {
// 使用 Ollama 配置 ChatClient,指定 Bespoke-Minicheck 模型
ChatClient chatClient = ChatClient.builder(
new OllamaChatModel("bespoke-minicheck")
).build();

// 创建 FactCheckingEvaluator
FactCheckingEvaluator evaluator = new FactCheckingEvaluator(chatClient);

// 准备测试数据
String document = "The Eiffel Tower is a wrought-iron lattice tower on the Champ de Mars in Paris, France. It was built between 1887 and 1889.";
String claim = "The Eiffel Tower was built in the 19th century.";

// 创建评估请求
EvaluationRequest evaluationRequest = evaluator.createEvaluationRequest(
"", // userText 在此场景中不使用
List.of(document),
claim
);

// 执行评估
EvaluationResponse evaluationResponse = evaluator.evaluate(evaluationRequest);

// 断言:该陈述应被判定为受文档支持
assertTrue(evaluationResponse.isSupported());
}
}

最佳实践

  • 选择合适的评估模型:评估模型不必与生成模型相同,选择擅长判断和评估的模型
  • 降低评估成本:对于事实核查等任务,可以使用小型专用模型(如 Bespoke Minicheck)来降低成本
  • 自定义提示词模板:根据具体的业务场景和语言(如中文),自定义评估提示词以获得更准确的评估结果
  • 在集成测试中使用:将评估器集成到自动化测试中,确保 RAG 流程等 AI 功能的质量回归
  • 结合多种评估器:可以同时使用 RelevancyEvaluatorFactCheckingEvaluator,从相关性和事实性两个维度全面评估 AI 响应